iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
Modern Web

小白的JavaScript讀書日記系列 第 24

Day24:Vue.js(六)

  • 分享至 

  • xImage
  •  

Day23小練習:
Try1:Try1:找出comics陣列中author:'冨樫義博'的漫畫。

<body>
  <div id="demo">
    <ul>
      <li v-for='(i,index) in search'>{{i.author}}:{{i.book}}</li>
    </ul>
  </div>
  <script>
    const vm = Vue.createApp({
      data() {
        return {
          comics: [
            { author: '冨樫義博', book: '幽遊白書' },
            { author: '高橋留美子', book: '亂馬1/2' },
            { author: '冨樫義博', book: '獵人' },
            { author: '臼井儀人', book: '蠟筆小新' },
            { author: '鳥山明', book: '七龍珠' },
            { author: '高橋留美子', book: '犬夜叉' },
            { author: '吾峠呼世晴', book: '鬼滅之刃' }
          ]
        }
      },
      computed: {
        search() {
          return this.comics.filter(i => i.author == '冨樫義博')
        }
      }
    }).mount('#demo')
  </script>
</body>

延續Day23的v-for
v-for與key
這邊改寫了上述的例子,可以先觀察一下沒綁上key的時候:

<body>
  <div id="demo">
    <h1>漫畫清單</h1>
    <ul>
      <li v-for="i in todoList">
        <label><input type="checkbox" v-model="i.isDone">{{i.id}}.{{i.author}}:{{i.book}}</label>
      </li>
    </ul>
    <h1>我的最愛</h1>
    <ul>
      <li v-for="i in doneList">
        <label><input type="checkbox" v-model="i.isDone">{{i.id}}.{{i.author}}:{{i.book}}</label>
      </li>
    </ul>
  </div>
  <script>
    const vm = Vue.createApp({
      data() {
        return {
          comics: [
            { author: '冨樫義博', book: '幽遊白書', id: '1', isDone: false },
            { author: '高橋留美子', book: '亂馬1/2', id: '2', isDone: false },
            { author: '冨樫義博', book: '獵人', id: '3', isDone: false },
            { author: '臼井儀人', book: '蠟筆小新', id: '4', isDone: false },
            { author: '鳥山明', book: '七龍珠', id: '5', isDone: false },
            { author: '高橋留美子', book: '犬夜叉', id: '6', isDone: false },
            { author: '吾峠呼世晴', book: '鬼滅之刃', id: '7', isDone: false }
          ]
        }
      },
      computed: {
        todoList() {
          return this.comics.filter(b => !b.isDone)
        },
        doneList() {
          return this.comics.filter(b => b.isDone)
        }

      }
    }).mount('#demo')
  </script>
</body>

我們可以從這個例子觀察到,當你勾選到1.冨樫義博:幽遊白書的時候,幽遊白書會被加到下方的我的最愛,但上方的2.高橋留美子:亂馬1/2同時也會被勾選,但是沒有加入下方的我的最愛。
但是,如果你反向來勾選加入,從7.吾峠呼世晴:鬼滅之刃開始勾選,並依序6..5..4這樣選擇,則不會發生上述的問題! 難道這是因為鬼滅沒有爛尾嗎(?
這是因為在Vue.js為了做到效能最佳化,會把已經渲染過的DOM節點拿來重複使用,意思是當我們在漫畫清單(todoList)勾選1.冨樫義博:幽遊白書的時候,我的最愛(doneList)會多出一個1.冨樫義博:幽遊白書的選項,對漫畫清單(todoList)來說,長度是減一,對應的元素少了一個,原本在幽遊白書的選項被更新,但checkBox卻被拿來重複使用就會被產生此現象,看一下圖吧:
https://ithelp.ithome.com.tw/upload/images/20200922/20129488eU1hdSWPQl.png
這邊是參閱Kuro大神改寫的...他解釋得更好,可以去看看!!!

為了避免這樣的情況發生,我們在li上綁定『唯一』的key屬性作為識別,可以確保每個元素的唯一性,當元素更新時,可以用key來判別。
在範例中的input加上:key="i.id",這樣就可確保上述的情況不會發生了!
<input type="checkbox" v-model="i.isDone" :key="i.id">
可以試看看呦!


生命週期與Hooks function

  • 生命週期:Vue的實體物件從建立,掛載,更新,銷毀移除
  • Hooks function:對應生命週期各階段處理的callback function

這邊可以參閱Vue提供的文件
下面這張是官網列出生命週期對應到Hooks function圖
https://ithelp.ithome.com.tw/upload/images/20200923/20129488egPO7mU3LC.png

從圖中我們可以看到Vue從建立到銷毀的幾個階段,對應的Hooks function

  • Vue實體建立:beforeCreatecreatedbeforeMountmounted
  • 更新:beforeUpdatedupdated
  • 銷毀:beforeUnmountunmounted
    Vue文件中有詳細介紹每個方法的作用。
    p.s.:在Vue.js v3.0中的改變
  • beforeCreate=>step()
  • created=>steup()
  • beforeMount=>onBeforeMount
  • mounted=>onMounted
  • beforeUpdated=>onBeforeUpdated
  • updated=>onUpdated

p.s.:Hooks function不能使用箭頭函式,因為在箭頭函式中綁定了父層級作用域的前後文,this將不會按照期望指向Vue的實體,會指向undefined。(這邊在使用methodscomputed中不能使用箭頭函式的觀念一樣)


今日總結

  • v-for 與 key 可以確保在渲染時的順序不會跑掉
  • 生命週期與Hooks function
  • Hooks function不可使用箭頭函式

上一篇
Day23:Vue.js(五)
下一篇
Day25:Vue.js(七)
系列文
小白的JavaScript讀書日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言